/*
 * VariableSetting.cpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#include "bfr/lpbCombinatorial/VariableSetting.hpp"

#include <algorithm>
#include <vector>

#include "bfr/Clause.hpp"
#include "bfr/ClauseSet.hpp"
#include "bfr/OccurrencePattern.hpp"

namespace bfr {

VariableSetting::~VariableSetting() { }

VariableSetting::
VariableSetting(const ClauseSet *dnf) {
	init(dnf);
}

void VariableSetting::init(const ClauseSet *dnf) {
    // create the occurrence patterns for each variable
    occurrences = new std::vector<OccurrencePattern*>();
    ClauseSet::const_iterator e = dnf->end();
    for (ClauseSet::const_iterator it = dnf->begin(); it != e; it++) {
        const Clause *c = *it;
	size_t clauseSize = c->size();
	Clause::const_iterator ce = c->end();
	for (Clause::const_iterator cit = c->begin(); cit != ce; cit++) {
		const Literal &l = *cit;
		size_t id = l.getId();
		// check if we have to extend the vector
		for (size_t i = occurrences->size(); i <= id; i++) {
			occurrences->push_back(new OccurrencePattern(i));
		}
		occurrences->operator[](id)->addOccurrence(clauseSize);
	}
    }
    // sort the occurrence pattern according the "importance order"
    std::sort(occurrences->begin(), occurrences->end(),
              OccurrencePattern::compareImportance);
    // save for each variable id the position in the ordering
    variablePos = std::vector<size_t>();
    variablePos.reserve(occurrences->size());

    // TODO: what happens if a variable has no occurrence?
    for(size_t i = 0; i < occurrences->size(); i++) {
        OccurrencePattern *op = occurrences->operator[](i);
	variablePos[op->getVariableId()] = i;
    }
}

std::vector<OccurrencePattern*> *VariableSetting::getOrderedPatterns() {
    return occurrences;
}

size_t VariableSetting::operator[](const size_t index) const {
    return occurrences->operator[](index)->getVariableId();
}

size_t VariableSetting::getPos(const size_t variableID) const {
    return variablePos[variableID];
}

size_t VariableSetting::size() const {
    return occurrences->size();
}

}
